import {
  canUse,
  isUndefined,
  _pick,
  isEmpty,
  StringIndexer,
  toString,
} from "mmb";
import { AppCTX } from "../../types/koaExtend";
import { getUser, updateMemberToken } from "../../service/userService";
import { Brand } from "../../service/declareTypes";
import {
  openBrand,
  openNew,
  getBrandByRemotePK,
  listUnmappingedBilinBrands,
  listBrandWithStatsByUserIDAsAdmin,
} from "../../service/brandService";
import {
  copySyncRemote,
  getSyncOfBrandSafely,
  listSyncMappingsBySyncID,
  listSyncRemotesBySyncID,
} from "../../service/syncService";
import {
  UniqueTokenExpiredError,
  getWebposBrandList,
  createWebposBrand,
} from "../../proxy/webPosProxy";


import pageMW from "../../middleware/pager";
import DataSource from "../../bg-enums/dataSource";
import Router from "koa-router";
const router = new Router();

// 获取开通星团的可选品牌
router.get(
  "/brd/brand-open/precondition/availableCustomerBrands",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;
    let user = await getUser(userId);

    let customerBrandsNotMapping: StringIndexer[] = [];
    let customerBrandsNotSynced: StringIndexer[] = [];

    const syncOfBrand = await getSyncOfBrandSafely();
    const syncId = syncOfBrand.syncId;
    console.log("syncId=>", syncId);
    if (user.memberToken) {
      console.log("user.uniqueToken=>", isEmpty(user.memberToken));
      let customerBrands: any;
      try {
        customerBrands = await getWebposBrandList(user.memberToken!).exec();
      } catch (err) {
        if (err instanceof UniqueTokenExpiredError) {
          console.log("availableCustomerBrands 处理MemberTokenExpiredError...");
          const memberToken = await err.compensate({
            mobile: user.mobile!,
            openId: user.openId,
          });
          user = await updateMemberToken({
            userId: user.userId,
            memberToken,
          });
          customerBrands = await getWebposBrandList(memberToken!).exec();
        } else {
          throw err;
        }
      }
      // console.log("getBrandList=>", JSON.stringify(customerBrands));

      const syncMappings = await listSyncMappingsBySyncID(syncId, {
        offset: 0,
        limit: 10000,
      });
      const syncedMappingPKs = syncMappings.items.map((it) => it.remotePK);

      customerBrandsNotMapping = customerBrands.filter(
        (cb) => !syncedMappingPKs.includes(toString(cb["remotePK"]))
      );
      // console.log("customerBrandsNotMapping=>", customerBrandsNotMapping);

      const syncRemotes = await listSyncRemotesBySyncID(syncId, {
        offset: 0,
        limit: 10000,
      });
      const syncedRemotePKs = syncRemotes.items.map((it) => it.remotePK);
      customerBrandsNotSynced = customerBrands.filter(
        (cb) => !syncedRemotePKs.includes(toString(cb["remotePK"]))
      );
      console.log("customerBrandsNotSynced=>", customerBrandsNotSynced);
    } else {
      ctx.throw(400, "invalid user no uniqueToken");
    }

    if (customerBrandsNotSynced.length > 0) {
      copySyncRemote({
        syncRemotes: customerBrandsNotSynced.map((c: StringIndexer) => ({
          syncRemoteId: "0",
          syncId,
          remoteObj: syncOfBrand.remoteObj,
          remotePK: c.remotePK,
          data: c,
        })),
      });
    }

    ctx.body = {
      total: customerBrandsNotMapping.length,
      rows: customerBrandsNotMapping,
    };
  }
);

// 开通星团
router.post("/brd/brand-open/open-old", async (ctx: AppCTX, next) => {
  let { name, intro, pic, remotePK } = ctx.request.body;
  const { userId } = ctx;

  let createLocal = false;
  let brand: Brand | undefined = undefined;
  if (isUndefined(remotePK)) {
    createLocal = true;
  } else {
    // 通过remotePK获取brand
    // 如果无法获取,则需要从本地创建
    brand = await getBrandByRemotePK(remotePK);
    if (!isUndefined(brand)) {
      ctx.throw(400, "品牌已开通");
    }
  }

  if (isUndefined(remotePK)) {
    let user = await getUser(userId);
    if (canUse(user.memberToken)) {
      let createdWebPosBrand: any;
      try {
        createdWebPosBrand = await createWebposBrand(user.memberToken!)
          .setBody({
            store_group_name: name,
          })
          .exec();
      } catch (err) {
        if (err instanceof UniqueTokenExpiredError) {
          console.log("availableCustomerBrands 处理MemberTokenExpiredError...");
          const memberToken = await err.compensate({
            mobile: user.mobile!,
            openId: user.openId,
          });
          user = await updateMemberToken({
            userId: user.userId,
            memberToken,
          });
          createdWebPosBrand = await createWebposBrand(memberToken)
            .setBody({
              store_group_name: name,
            })
            .exec();
        } else {
          throw err;
        }
      }

      console.log("remotePK=>", remotePK);
      remotePK = createdWebPosBrand.remotePK;
    } else {
      ctx.throw("invalid user no uniqueToken");
    }
  }

  const origin = createLocal ? DataSource.LOCAL : DataSource.REMOTE;

  brand = await openBrand({ origin, name, intro, pic, remotePK, userId });

  console.log("opened brand=>", brand);
  // 2、如果是具有remote_pk(pos里的sg_id),则需要同步仓库信息,后续通过消息系统同步
  console.log(
    "warnig=> 2、如果createLocal = true,则需要同步仓库信息,后续通过消息系统同步"
  );

  const output = _pick(brand, "brandId", "name", "intro", "pic", "remotePK");

  ctx.body = {
    ...output,
  };
});

// 开通星团
router.post("/brd/brand-open/open", async (ctx: AppCTX, next) => {
  let { name, intro, pic, remotePkOfBrand, remotePkOfEmployee } = ctx.request.body;
  const { userId } = ctx;
  const brand = await openNew({ name, intro, pic, remotePkOfBrand, remotePkOfEmployee, userId });

  // console.log("open new brand=>", brand);

  const output = _pick(brand, "brandId");

  ctx.body = {
    ...output,
  };
});

// 获取该账号可开通的比邻品牌列表
router.get(
  "manage-brands",
  "/brd/brand-open/bilinBrands",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;

    const bilinBrands = await listUnmappingedBilinBrands(userId);

    ctx.body = {
      total: bilinBrands.length,
      rows: bilinBrands,
    };
  }
);

// 获取该账号可切换品牌列表
router.get(
  "manage-brands",
  "/brd/brand-open/manages",
  pageMW,
  async (ctx: AppCTX, next) => {
    const { userId, limit, offset } = ctx;
    const { brandId } = ctx.params;
    const { total, items } = await listBrandWithStatsByUserIDAsAdmin(
      userId,
      {
        limit,
        offset,
      }
    );

    ctx.body = {
      total,
      rows: items.map((it) => ({
        ..._pick(
          it,
          "brandId",
          "name",
          "pic",
          "fansCount",
          // "adminCount",
          // "spokesmanCount",
          "publishActivityCount"
        ),
      })),
    };
  }
);

export default router;
